package org.jeecg.modules.system.util;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang.StringUtils;
import org.jeecg.common.constant.enums.SysAuthType;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.IscConfig;
import org.jeecg.modules.system.entity.SysPermission;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.springframework.stereotype.Component;

import com.gcloud.mesh.framework.core.util.JsonUtil;
import com.sgcc.isc.core.orm.complex.FunctionNode;
import com.sgcc.isc.core.orm.complex.FunctionTree;
import com.sgcc.isc.core.orm.identity.User;
import com.sgcc.isc.core.orm.resource.Function;
import com.sgcc.isc.core.orm.role.Role;
import com.sgcc.isc.service.adapter.factory.AdapterFactory;
import com.sgcc.isc.service.adapter.helper.IResourceService;
import com.sgcc.isc.service.adapter.utils.Base64Util;
import com.sgcc.isc.service.adapter.utils.CASClient;
import com.sgcc.isc.service.adapter.utils.CASTicket;

import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.log.Log;

@Slf4j
@Component
public class IscUtil {

	public static Map<String, String> urlModuleMap = new HashMap<>();

	public static CASTicket getCASTicket(String userName, String password, String service) {
		String server = IscConfig.getIscServer() + "/isc_sso/v1/tickets";
		return CASClient.getTicket(server, userName, new String(Base64Util.encode(password.getBytes(StandardCharsets.UTF_8))), service);
	}

	public static SysUser iscUserToSysUser(User user) {
		SysUser sysUser = new SysUser();
		iscUserToSysUser(sysUser, user);
		return sysUser;
	}

	/**
	 * 将IscUserVo转成SysUser
	 *
	 * @param user
	 * @return
	 */
	public static void iscUserToSysUser(SysUser sysUser, User user) {
		// id不会改变
		if (sysUser.getId() == null) {
			sysUser.setId(user.getId());
		}
		if (sysUser.getSalt() == null) {
			sysUser.setSalt(oConvertUtils.randomGen(8));
		}
		if (!Objects.equals(sysUser.getUsername(), user.getUserName())) {
			sysUser.setUsername(user.getUserName());
		}
		String password = PasswordUtil.encrypt(user.getUserName(), user.getPassword(), sysUser.getSalt());
		if (!Objects.equals(password, sysUser.getPassword())) {
			sysUser.setPassword(password);
		}
		if (!Objects.equals(sysUser.getRealname(), user.getName())) {
			sysUser.setRealname(user.getName());
		}
		if (!Objects.equals(sysUser.getAvatar(), user.getPhoto())) {
			sysUser.setAvatar(user.getPhoto());
		}
		String pattern = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		try {
			if (user.getBirthDate() != null) {
				Date date = sdf.parse(user.getBirthDate());
				if (!Objects.equals(date, sysUser.getBirthday())) {
					sysUser.setBirthday(date);
				}
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		if (user.getSexCode() != null && !Objects.equals(sysUser.getSex(), Integer.parseInt(user.getSexCode()))) {
			sysUser.setSex(Integer.parseInt(user.getSexCode()));
		}

		if (!Objects.equals(sysUser.getEmail(), user.getEmail())) {
			sysUser.setEmail(user.getEmail());
		}
		if (!Objects.equals(sysUser.getPhone(), user.getMobile())) {
			sysUser.setPhone(user.getMobile());
		}
		if (!Objects.equals(sysUser.getOrgCode(), user.getBaseOrgId())) {
			sysUser.setOrgCode(user.getBaseOrgId());
		}
		if (!Objects.equals(sysUser.getOrgCodeTxt(), user.getOrgAnisationName())) {
			sysUser.setOrgCodeTxt(user.getOrgAnisationName());
		}
		if (user.getState() != null && !Objects.equals(sysUser.getStatus(), Integer.parseInt(user.getState()))) {
			sysUser.setStatus(Integer.parseInt(user.getState()));
		}
		// 如果是新增加user，默认为正常，如果数据库中已经指定删除状态，保留。
		if (sysUser.getDelFlag() == null) {
			sysUser.setDelFlag(0);
		}

		// Unicode->workNo
		if (!Objects.equals(sysUser.getWorkNo(), user.getUnicode())) {
			sysUser.setWorkNo(user.getUnicode());
		}

		if (!Objects.equals(sysUser.getPost(), user.getTitle())) {
			sysUser.setPost(user.getTitle());
		}
		if (!Objects.equals(sysUser.getTelephone(), user.getTelephoneNumber())) {
			sysUser.setTelephone(user.getTelephoneNumber());
		}

		sysUser.setThirdId(user.getId());
		sysUser.setThirdType(SysAuthType.ISC.getName());

		try {
			if (user.getStartUsefulLife() != null) {
				Date createTime = sdf.parse(user.getStartUsefulLife());
				if (!Objects.equals(sysUser.getCreateTime(), createTime)) {
					sysUser.setCreateTime(createTime);
				}
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		// createBy,updateBy,updateTime,activitiSync,userIdentity
		// departIds,thirdId,thirdType,relTenantIds

	}

	public static void sysPermissionToFunction(SysPermission sysPermission, Function function) {
		if (function.getId() == null) {
			function.setId(sysPermission.getId());
		}
		if (!Objects.equals(function.getCode(), sysPermission.getId())) {
			function.setCode(sysPermission.getId());
		}
		if (!Objects.equals(function.getFuncId(), sysPermission.getParentId())) {
			function.setFuncId(sysPermission.getParentId());
		}
		if (!Objects.equals(function.getName(), sysPermission.getName())) {
			function.setName(sysPermission.getName());
		}
		if (!Objects.equals(function.getUrl(), sysPermission.getUrl())) {
			function.setUrl(sysPermission.getUrl());
		}
		if (!Objects.equals(function.getFuncOtherInfo(), sysPermission.getDescription())) {
			function.setFuncOtherInfo(sysPermission.getDescription());
		}
		if (!Objects.equals(function.getIsAvaliable(), sysPermission.getStatus())) {
			function.setIsAvaliable(sysPermission.getStatus());
		}
		if (!Objects.equals(function.getBusiCode(), sysPermission.getPerms())) {
			function.setBusiCode(sysPermission.getPerms());
		}
		function.setSystemId(IscConfig.getIscAppId());
		String funcType;
		switch (sysPermission.getMenuType()) {
		case 0:
			funcType = "001";
			break;
		case 1:
			funcType = "08";
			break;
		case 2:
			funcType = "002";
			break;
		default:
			funcType = "001";
		}
		function.setFuncType(funcType);
		function.setFuncCategory(funcType);

	}

	public static SysPermission iscFunctionToSysPermission(Function function) {
		SysPermission sysPermission = new SysPermission();
		iscFunctionToSysPermission(function, sysPermission);
		return sysPermission;
	}

	public static void iscFunctionToSysPermission(Function function, SysPermission sysPermission) {
		if (sysPermission.getId() == null) {
			sysPermission.setId(function.getId());
		}
		if (!Objects.equals(sysPermission.getParentId(), function.getFuncId())) {
			sysPermission.setParentId(function.getFuncId());
		}
		if (!Objects.equals(sysPermission.getName(), function.getName())) {
			sysPermission.setName(function.getName());
		}
		// 防止多个url
		if (!Objects.equals(sysPermission.getUrl(), function.getUrl())) {
			if (function.getUrl() != null) {
				if (function.getUrl().split(",").length < 2) {
					sysPermission.setUrl(function.getUrl());
				} else {
					return;
				}
			}
		}
		if (!Objects.equals(sysPermission.getDescription(), function.getFuncOtherInfo())) {
			sysPermission.setDescription(function.getFuncOtherInfo());
		}
		// if (function.getIsAvaliable() != null &&
		// function.getIsAvaliable().length() < 3 &&
		// !Objects.equals(sysPermission.getStatus(),
		// function.getIsAvaliable())) {
		// sysPermission.setStatus(function.getIsAvaliable());
		// }
		if (!Objects.equals(sysPermission.getDelFlag(), 1)) {
			sysPermission.setDelFlag(0);
		}
		if (!Objects.equals(sysPermission.getPerms(), function.getBusiCode())) {
			sysPermission.setPerms(function.getBusiCode());
		}

		int menuType;
		switch (function.getFuncType()) {
		case "001":
			menuType = 0;
			break;
		case "002":
			menuType = 2;
			break;
		case "08":
			menuType = 1;
			break;
		default:
			menuType = 0;
			break;
		}
		sysPermission.setMenuType(menuType);

	}

	public static SysRole iscRoleToSysRole(Role iscRole, SysRole sysRole) {
		if (sysRole.getId() == null) {
			sysRole.setId(iscRole.getId());
		}
		if (!Objects.equals(iscRole.getName(), sysRole.getRoleName())) {
			sysRole.setRoleName(iscRole.getName());
		}
		if (!Objects.equals(iscRole.getCode(), sysRole.getRoleCode())) {
			sysRole.setRoleCode(iscRole.getCode());
		}
		// description,createBy,createTime,updateBy,updateTime
		return sysRole;
	}

	public static SysRole iscRoleToSysRole(Role iscRole) {
		return iscRoleToSysRole(iscRole, new SysRole());
	}

	/**
	 * 判断账号是否存在
	 *
	 * @param msg
	 * @param name
	 * @return
	 */
	public static boolean isUserNotExist(String msg, String name) {
		return msg.startsWith("帐号") && msg.endsWith("不存在") && msg.contains(name);
	}

	public static boolean isPwdIncorrect(String msg) {
		return msg.contains("密码不正确");
	}

	public static Map<String, String> getLogModule(String userId) {

		SysUserMapper sysUserMapper = SpringContextUtils.getBean(SysUserMapper.class);

		SysUser user = sysUserMapper.selectById(userId);

		Map<String, String> urlModuleMap = new HashMap<>();

		if (user != null) {
			try {
				IResourceService resourceService = AdapterFactory.getResourceService();
				FunctionTree funcTree = resourceService.getFuncTree(user.getThirdId(), IscConfig.getIscAppId(), null);

				List<FunctionNode> functionNodes = funcTree.getFuncNode();

				log.info("functionNodes-" + user.getUsername() + ":" + JsonUtil.listToJson(functionNodes));

				findModule(functionNodes, urlModuleMap);
			} catch (Exception e) {
				Log.error(e.getMessage(), e);
			}
		}
		return urlModuleMap;
	}

	private static void findModule(List<FunctionNode> functionNodes, Map<String, String> urlModuleMap) {
		if (functionNodes != null) {
			for (FunctionNode functionNode : functionNodes) {
				Function func = functionNode.getCurrentNode();
				if (func != null) {
					if (StringUtils.isNotBlank(func.getUrl()) && func.getUrl().startsWith("/f") && func.getUrl().length() < 9) {
						urlModuleMap.put(func.getUrl(), func.getName());
					}

					if (StringUtils.isNotBlank(func.getUrl()) && func.getUrl().startsWith("/f") && func.getUrl().length() == 8) {
						String moduleName = "";
						if (StringUtils.isNotBlank(urlModuleMap.get(func.getUrl().substring(0, 4)))) {
							moduleName += urlModuleMap.get(func.getUrl().substring(0, 4));
						}

						if (StringUtils.isNotBlank(urlModuleMap.get(func.getUrl().substring(0, 6)))) {
							if (StringUtils.isNotBlank(moduleName)) {
								moduleName += "-";
							}
							moduleName += urlModuleMap.get(func.getUrl().substring(0, 6));
						}

						if (StringUtils.isNotBlank(moduleName)) {
							moduleName += "-";
						}

						moduleName += func.getName();
						getUrlModule(urlModuleMap, functionNode.getNextNode(), moduleName, null);
					} else {
						findModule(functionNode.getNextNode(), urlModuleMap);
					}
				}
			}
		}
	}

	private static void getUrlModule(Map<String, String> urlModuleMap, List<FunctionNode> functionNodes, String moduleName, String tabName) {
		if (functionNodes != null) {
			for (FunctionNode functionNode : functionNodes) {
				Function func = functionNode.getCurrentNode();
				if (func != null) {
					if ("08".equals(func.getFuncType())) {
						if (StringUtils.isNotBlank(func.getName())) {
							tabName = func.getName();
						}
					}

					if ("002".equals(func.getFuncType())) {
						if (StringUtils.isNotBlank(func.getUrl())) {
							if (StringUtils.isNotBlank(tabName)) {
								urlModuleMap.put(func.getUrl(), moduleName + "-" + tabName);
							} else {
								urlModuleMap.put(func.getUrl(), moduleName);
							}
						}
					}
				}

				if (functionNode.getNextNode() != null && functionNode.getNextNode().size() > 0) {
					getUrlModule(urlModuleMap, functionNode.getNextNode(), moduleName, tabName);
				}
			}
		}
	}
}
